package com.zxmzy.scaffold.http.tools

import android.text.TextUtils
import android.util.Log
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject

/**
 * @author zhangxiaoming
 * @date 2023/8/24
 * @description
 */
object OkLog {
    private const val TAG = "OKHttp"
    private const val LINE_SEPARATOR: String = "\n"
    private const val JSON_INDENT = 4
    private const val STACK_TRACE_INDEX_4 = 4
    private const val SUFFIX = ".java"
    fun log(msg: String) {
        if (msg.isEmpty()) return
        val newMsg = msg.trim()
        val message: String = try {
            when {
                newMsg.startsWith("{") -> {
                    val jsonObject = JSONObject(newMsg)
                    jsonObject.toString(JSON_INDENT)
                }

                newMsg.startsWith("[") -> {
                    val jsonArray = JSONArray(newMsg)
                    jsonArray.toString(JSON_INDENT)
                }

                else -> newMsg
            }
        } catch (e: JSONException) {
            newMsg
        }
        val lines: List<String> = message.split(LINE_SEPARATOR)
        lines.forEach {
            Log.i(TAG, "║ $it")
        }
    }

    fun start(hint: String) {
        printLine(TAG, true, hint)
//        log(getStackTrace() + LINE_SEPARATOR)
    }

    fun end(hint: String) {
        printLine(TAG, false, hint)
    }

    private fun printLine(tag: String, isTop: Boolean, hint: String) {
        val newHint = hint.ifEmpty { "════════" }
        if (isTop) {
            Log.i(tag, "╔════════ $newHint ══════════════════════════════════")
        } else {
            Log.i(tag, "╚════════ $newHint ══════════════════════════════════")
        }
    }

    private fun getStackTrace(): String {
        val stackTrace = Thread.currentThread().stackTrace
        val targetElement: StackTraceElement = stackTrace[STACK_TRACE_INDEX_4]
        var className: String = targetElement.className
        val classNameInfo: List<String> = className.split("\\.")
        if (classNameInfo.isNotEmpty()) {
            className = classNameInfo[classNameInfo.size - 1] + SUFFIX
        }
        if (className.contains("$")) {
            className = className.split("$")[0] + SUFFIX
        }
        val methodName = targetElement.methodName
        var lineNumber = targetElement.lineNumber
        if (lineNumber <= 0) {
            lineNumber = 0
        }
        return "[ ($className:$lineNumber)#$methodName]"
    }
}